﻿/*
 * Author: .net follower (http://dotnetfollower.com)
 * Url: http://bdcrequestlib.codeplex.com/
 * Title: SharePoint Bdc Requests
 * Copyright: � 2012 .net follower 
 * Usage: software is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 */

using System.Collections.Generic;
using System.Linq;
using System.Data;
using Microsoft.BusinessData.MetadataModel;
using Microsoft.BusinessData.Runtime;
using Microsoft.SharePoint.BusinessData.Infrastructure;

namespace SharePointBdcRequests
{
    /// <summary>
    /// Abstracts the retrieving of Business Data Items from BDC Metadata Store
    /// </summary>
    public abstract class BdcRequest : BdcMetaRequest
    {
        #region fields & properties
        protected readonly DataReceiver<List<IEntityInstance>> _iEntityInstances = new DataReceiver<List<IEntityInstance>>();
        protected readonly DataReceiver<DataTable>             _dataTable        = new DataReceiver<DataTable>();

        /// <summary>
        /// Indicates if result values will be formatted
        /// </summary>
        public bool FormattedValues;
        
        /// <summary>
        /// A DataTable containing rows, which represent either records from a database or objects returned by a Web service
        /// </summary>
        public virtual DataTable FoundEntityInstancesAsDataTable
        {
            get { return !_dataTable.Received ? (_dataTable.Data = GetDataTable()) : _dataTable.Data; }
        }

        /// <summary>
        /// A list of the found EntityInstances
        /// </summary>
        protected virtual List<IEntityInstance> EntityInstances
        {
            get { return !_iEntityInstances.Received ? (_iEntityInstances.Data = GetEntityInstances()) : _iEntityInstances.Data; }
        }

        /// <summary>
        /// Fields making up the view of the found Business Data Item
        /// </summary>
        public override List<IField> FoundViewFields
        {
            get { return EntityInstances.Count > 0 ? EntityInstances[0].ViewDefinition.Fields.ToList() : new List<IField>(0); }
        }
        #endregion

        #region public methods
        /// <summary>
        /// Initializes a new instance of the BdcRequest class
        /// </summary>
        /// <param name="bdcRequestParams">Input parameters</param>
        protected BdcRequest(BdcRequestParams bdcRequestParams) : base(bdcRequestParams) { }

        /// <summary>
        /// Returns an encoded Business Data Item identifier.
        /// </summary>
        /// <param name="entityInstance">A Business Data Item</param>
        /// <returns>An encoded identifier</returns>
        public static string GetEntityInstanceEncodedId(IEntityInstance entityInstance)
        {
            return EntityInstanceIdEncoder.EncodeEntityInstanceId(entityInstance.GetIdentity().GetIdentifierValues().ToArray());
        }

        /// <summary>
        /// Returns a Business Data Item identifier as an array of objects
        /// </summary>
        /// <param name="entityInstance">A Business Data Item</param>
        /// <returns>An array of objects making up the identifier</returns>
        public static object[] GetEntityInstanceIds(IEntityInstance entityInstance)
        {
            return entityInstance.GetIdentity().GetIdentifierValues();
        }

        /// <summary>
        /// Releases resources
        /// </summary>
        public override void Dispose()
        {
            _iEntityInstances.Reset();
            _dataTable.Reset();
            base.Dispose();
        }
        #endregion

        #region internal methods
        /// <summary>
        /// Gets a DataTable, where every row is one of the found BDC Entity Instances
        /// </summary>
        /// <returns>a DataTable containing the found BDC Entity Instances</returns>
        protected abstract DataTable GetDataTable();

        /// <summary>
        /// Gets the found BDC Entity Instances
        /// </summary>
        /// <returns>A list of the found BDC Entity Instances</returns>
        protected virtual List<IEntityInstance> GetEntityInstances()
        {
            return new List<IEntityInstance>(0);
        }

        /// <summary>
        /// Returns a string for searching in External Data Sources. The string is based on a passed value to search and depends on a passed search mode
        /// </summary>
        /// <param name="valueToSearch">A value to search</param>
        /// <param name="searchValueMode">A search mode</param>
        /// <returns>An adapted for searching string</returns>
        protected static string GetSearchPattern(string valueToSearch, SearchValueModes searchValueMode)
        {
            switch (searchValueMode)
            {
                //case SearchValueModes.Equals:     return valueToSearch;
                case SearchValueModes.Contains:   return "%" + valueToSearch + "%";
                case SearchValueModes.EndsWith:   return "%" + valueToSearch;
                case SearchValueModes.StartsWith: return valueToSearch + "%";
            }
            return valueToSearch;
        }
        #endregion
    }
}
